package io.bsly.common.utils;

import lombok.Data;
import okhttp3.*;

import java.util.Map;
import java.util.Objects;

/**
 * @Author: Hank
 * @Date: 2019/6/20 11:02
 * @Description: TODO
 */
public class HttpUtil {
    private static OkHttpClient okHttpClient;
    private static OkHttpClient getInstance() {
        if (okHttpClient == null) {
            synchronized (HttpUtil.class) {
                if (okHttpClient == null) {
                    okHttpClient = new OkHttpClient.Builder()
                            // .connectTimeout(10, TimeUnit.SECONDS) // 10秒连接超时
                            // .writeTimeout(10, TimeUnit.SECONDS) // 10m秒写入超时
                            // .readTimeout(10, TimeUnit.SECONDS)// 10 秒读取超时
                            // .addInterceptor(new HttpHeaderInterceptor())//头部信息统一处理
                            // .addInterceptor(new CommonParamsInterceptor())//公共参数统一处理
                            .build();
                }
            }
        }
        return okHttpClient;
    }

    /**
     * 调用okhttp的newCall方法
     * @param request
     * @return
     */
    public static ResponseData execNewCall(Request request) {
        Response response = null;
        ResponseData responseData = new ResponseData();
        try {
            response = getInstance().newCall(request).execute();
            responseData.setCode(response.code());
            responseData.setSuccess(response.isSuccessful());
            if (response.isSuccessful()) {
                responseData.setData(Objects.requireNonNull(response.body()).string());
            }
            return responseData;
        } catch (Exception e) {
            e.printStackTrace();
            responseData.setData(e.getMessage());
        } finally {
            if (response != null) {
                response.close();
            }
        }
        return responseData;
    }

    /**
     * 根据map获取get请求参数
     * @param queries
     * @return
     */
    public static StringBuffer getQueryString(String url, Map<String,String> queries) {
        StringBuffer sb = new StringBuffer(url);
        if (queries != null && queries.keySet().size() > 0) {
            boolean firstFlag = true;
            for (Map.Entry entry : queries.entrySet()) {
                if (firstFlag) {
                    sb.append("?").append(entry.getKey()).append("=").append(entry.getValue());
                    firstFlag = false;
                } else {
                    sb.append("&").append(entry.getKey()).append("=").append(entry.getValue());
                }
            }
        }
        return sb;
    }

    /**
     * get
     * @param url     请求的url
     * @param queries 请求的参数，在浏览器？后面的数据，没有可以传null
     * @return
     */
    public static ResponseData get(String url, Map<String, String> queries) {
        StringBuffer sb = getQueryString(url, queries);
        Request request = new Request.Builder()
                .url(sb.toString())
                .build();
        return execNewCall(request);
    }

    /**
     * Post 表单
     *
     * @param url 请求的url
     * @param formMap 提交的参数
     * @return
     */
    public static ResponseData post(String url, Map<String, String> formMap) {
        FormBody.Builder builder = new FormBody.Builder();
        //添加参数
        if (formMap != null && formMap.keySet().size() > 0) {
            for (String key : formMap.keySet()) {
                builder.add(key, formMap.get(key));
            }
        }
        Request request = new Request.Builder()
                .url(url)
                .post(builder.build())
                .build();
        return execNewCall(request);
    }


    /**
     * Post Json
     * @param url 请求的url
     * @param json 提交的Json
     * @return
     */
    public static ResponseData post(String url, String json) {
        RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), json);
        Request request = new Request.Builder()
                .url(url)
                .post(requestBody)
                .build();
        return execNewCall(request);
    }

    @Data
    public static class ResponseData {
        private int code;
        private boolean success;
        private String data;
    }
}
